#include "head.h"

// 功能：使用md5加密，获取随机的8位盐值
int getSalt(char *salt){

    char ch[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxwz/.";
    srand(time(NULL));
    int len = strlen(ch);
    salt[0] = '$';
    salt[1] = '1';
    salt[2] = '$';
    for(int i = 0; i < 8; i++){
        salt[3+i] = ch[rand()%len];
    }
    salt[11] = '$';
    salt[12] = '\0';
    return 0;
}

// 功能：对输入的内容进行验证，预防SQL注入
int SQLVerity(char *sql){
    for(size_t i = 0; i < strlen(sql); i++){
        if(sql[i] == ')' || sql[i] == ';'){
            return -1;
        }
    }
    return 0;
}


// 功能：登录验证                    
int loginVerity(MYSQL *mysql,int sockfd, train_t *mess){
    char sql[8192];
    bzero(sql, sizeof(sql));

    // 用户名存在问题
    int ret = SQLVerity(mess->buf);
    if(ret != 0){
        int responseRet = TLVResponse(sockfd, "userName error", IS_NOT_OK);
        if(responseRet == -1){
            return -1;
        }
        return 0;
    }
    sprintf(sql, "select id,salt,password from user_info where username = '%s';", mess->buf);
    
    // 查询数据库
    ret = mysql_query(mysql, sql);
    if(ret != 0){
        int responseRet = TLVResponse(sockfd, "mysql error", IS_NOT_OK);
        if(responseRet == -1){
            return -1;
        }
        fprintf(stderr, "mysql error :%s\n", mysql_error(mysql));
        return 0;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    
    int row = mysql_num_rows(res);
    // 用户不存在情况
    if(row == 0){
        TLVResponse(sockfd, "user does not exit", IS_NOT_OK);
        return 0;
    }
    // 用户存在，发送盐值
    MYSQL_ROW resultRow = mysql_fetch_row(res);
    char *salt = resultRow[1];
    
    TLVResponse(sockfd, salt, LOGIN_SALT);

    recvRequest(sockfd, mess);

    // 验证密码的正确性
    if(strcmp(resultRow[2], mess->buf)){
        // 密码错误
        TLVResponse(sockfd, "password mistake", IS_NOT_OK);
        return 0;
    }
    TLVResponse(sockfd, "login success", IS_OK);
    return atoi(resultRow[0]);
}

// 功能：查表，看用户名是否存在，并返回id
int userIsExist(MYSQL *mysql, char *userName){
    char sql[4096];
    bzero(sql, sizeof(sql));

    sprintf(sql, "select id from user_info where userName = '%s';", userName);
    int ret = mysql_query(mysql, sql);
    if(ret != 0){
        printf("error : %s\n", mysql_error(mysql));
        return -1;
    }
    
    MYSQL_RES *res = mysql_store_result(mysql);
    int row = mysql_num_rows(res);
    if(row == 0){
        return 0;
    }
    
    MYSQL_ROW retRow = mysql_fetch_row(res);
    return atoi(retRow[0]);
}

// 功能：获取指定用户的根id
int getFileInfoId(MYSQL *mysql, int userId){
    char sql[1024];
    bzero(sql, sizeof(sql));

    sprintf(sql, "select id from file_info where userId = %d and fileName = '/'", userId);
    int ret = mysql_query(mysql, sql);
    if(ret != 0){
        printf("mysql error : %s\n", mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    MYSQL_ROW retROW = mysql_fetch_row(res);

    return atoi(retROW[0]);
}
                                     
// 功能：注册验证
// 返回值：
//      用-1表示用户断开连接
//      用0表示验证错误
//      用userId表示成功注册
int signUpVerity(MYSQL *mysql, int sockfd, train_t *mess){
    
    // 检查用户名是否存在
    int ret = userIsExist(mysql, mess->buf);
    if(ret != 0){
        int responseRet = TLVResponse(sockfd, "userName is exist", IS_NOT_OK);
        if(responseRet == -1){
            return -1;
        }
        return 0;
    }
    char salt[13];
    bzero(salt, sizeof(salt));

    // 生成盐值
    getSalt(salt);
    TLVResponse(sockfd, salt, SIGNUP_SALT);
    // 收取密文
    train_t train;
    recvRequest(sockfd, &train);
    
    // 插入
    char sql[10240];
    bzero(sql, sizeof(sql));
    sprintf(sql, "insert into user_info (username,salt,password,pwd)values('%s', '%s', '%s', %d);", mess->buf, salt, train.buf, 0);
    ret = mysql_query(mysql, sql);
    if(ret != 0){
        int responseRet = TLVResponse(sockfd, mysql_error(mysql), IS_NOT_OK);
        if(responseRet == -1){
            return -1;
        }
        return -2;
    }
    
    int userId = userIsExist(mysql, mess->buf);

    // 给该用户创建根目录
    bzero(sql, sizeof(sql));
    sprintf(sql, "insert into file_info (fileName,parentId,userId,path,fileType)values('/', 0, %d, '/', 'd');", userId);
    ret = mysql_query(mysql, sql);
    if(ret != 0){
        TLVResponse(sockfd, mysql_error(mysql), IS_NOT_OK);
        return -2;
    }
    // 获取根id赋给pwd
    int sourceId = getFileInfoId(mysql, userId);
    
    bzero(sql, sizeof(sql));
    sprintf(sql, "update user_info set pwd = %d where id = %d;", sourceId, userId);
    ret = mysql_query(mysql, sql);
    if(ret != 0){
        int responseRet = TLVResponse(sockfd, mysql_error(mysql), IS_NOT_OK);
        if(responseRet == -1){
            return -1;
        }
        return 0;
    }
    // 响应成功
    TLVResponse(sockfd, "signUp success", IS_OK);

    return userId;
}
